#include <clusnet/base/FixedBuffer.h>
#include <gtest/gtest.h>

#include <string>

class FixedBufferTest : public testing::Test
{
    public:
        FixedBufferTest() = default;
        virtual ~FixedBufferTest() = default;
        FixedBufferTest(const FixedBufferTest&) = delete;
        FixedBufferTest& operator= (const FixedBufferTest&) = delete;

        virtual void SetUp() override
        {
            buffer.append("hello", 5);
        }

    protected:
        clusnet::base::FixedBuffer<16>    buffer;
};

TEST_F(FixedBufferTest, Test_append)
{
    auto str = buffer.toString();
    auto avail = buffer.avail();
    buffer.append("hello", 4);
    buffer.append("hello", 0);
    ASSERT_EQ(buffer.toString(), str + "hell");
    ASSERT_EQ(buffer.length(), str.length() + 4);
    ASSERT_EQ(buffer.avail(), avail - 4);
}

TEST_F(FixedBufferTest, Test_bzero)
{
    buffer.bzero();
    std::string zero(buffer.length(), '\0');
    ASSERT_EQ(buffer.length(), zero.length());
    ASSERT_EQ(buffer.toString(), zero);
}

TEST_F(FixedBufferTest, Test_reset)
{
    buffer.reset();
    ASSERT_EQ(buffer.length(), 0);
    ASSERT_TRUE(buffer.toString().empty());
}

TEST_F(FixedBufferTest, Test_copyConstruct)
{
    auto leftCopyBuffer(buffer);
    ASSERT_EQ(buffer.length(), leftCopyBuffer.length());
    ASSERT_EQ(buffer.toString(), leftCopyBuffer.toString());

    auto rightCopyBuffer(std::move(leftCopyBuffer));
    ASSERT_EQ(buffer.length(), rightCopyBuffer.length());
    ASSERT_EQ(buffer.toString(), rightCopyBuffer.toString());
}

TEST_F(FixedBufferTest, Test_assign)
{
    decltype(buffer) leftAssignBuffer;
    leftAssignBuffer = buffer;
    ASSERT_EQ(buffer.length(), leftAssignBuffer.length());
    ASSERT_EQ(buffer.toString(), leftAssignBuffer.toString());

    decltype(buffer) rightAssignBuffer;
    rightAssignBuffer = std::move(leftAssignBuffer);
    ASSERT_EQ(buffer.length(), rightAssignBuffer.length());
    ASSERT_EQ(buffer.toString(), rightAssignBuffer.toString());
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
